<template>
  <g class="graphics" :class="{tracking: localTracking}">
    <g class="bounds" v-track.stop="handleTrack">
      <polygon class="polygon" :points="polygonPoints" :stroke-width="1 / Math.max(scale, 1)"></polygon>

      <line
        class="line"
        v-for="line in lines"
        :key="`line_${line.id}`"
        :x1="line.p1.x"
        :y1="line.p1.y"
        :x2="line.p2.x"
        :y2="line.p2.y"
        :data-point-id="line.id"
        v-tap.stop="handlePathTap"
        v-bind:stroke-width="20 /  Math.max(scale, 1)"
      ></line>
      <PolygonPoint
        v-for="point in points"
        :key="`point_${point.id}`"
        :pointId="point.id"
        :offsetX="point.x"
        :offsetY="point.y"
        v-on:track.stop="handlePointTrack"
      />
    </g>
          
  </g>
</template>

<script>
import PolygonPoint from "@/widgets/components/PolygonPoint";
export default {
  name: "PolygonWidget",
  components: {
    PolygonPoint
  },
  props: {
    width: {
      type: Number,
      default: 0
    },
    height: {
      type: Number,
      default: 0
    },
    offsetX: {
      type: Number,
      default: 0
    },
    offsetY: {
      type: Number,
      default: 0
    },
    widgetId: {
      type: Number,
      default: 0
    },
    pointIds: {
      type: Array,
      default() {
        return [];
      }
    }
  },
  data() {
    return {
      localTracking: false,
      localPointMovementX: 0,
      localPointMovementY: 0,
      localMovementPointId: 0,
      localSelectedPointId: 0
    };
  },
  computed: {
    scale() {
      return this.$store.state.canvas.scale;
    },
    points() {
      const pointMap = this.$store.state.points.byId;
      return this.pointIds.map(pointId => {
        const point = pointMap[pointId];
        if (this.localMovementPointId === pointId) {
          return {
            id: point.id,
            x: this.offsetX + point.dx + this.localPointMovementX,
            y: this.offsetY + point.dy + this.localPointMovementY
          };
        }
        return {
          id: point.id,
          x: this.offsetX + point.dx,
          y: this.offsetY + point.dy
        };
      });
    },
    polygonPoints() {
      const points = [];
      this.points.forEach(point => {
        points.push(point.x);
        points.push(point.y);
      });
      return points.join(" ");
    },
    lines() {
      const lines = [];
      const newPoints = [...this.points];      
      const [first] = this.points;
      newPoints.push({
        ...first,
        id: -1
      });
      for (let i = 0; i < newPoints.length - 1; i++) {
        const currentPoint = newPoints[i];
        const nextPoint = newPoints[i + 1];
        
        lines.push({
          id: currentPoint.id,
          p1: currentPoint,
          p2: nextPoint
        });
      }
      return lines;
    }
  },
  methods: {
    handleTrack(event) {
      event.detail.widgetId = this.widgetId;

      switch (event.detail.state) {
        case "start":
          this.localTracking = true;
          break;
        case "end":
          this.localTracking = false;
          break;
      }
      this.$emit("track", event);
    },
    handlePointTrack(event) {
      const {
        detail: { dx, dy, state, pointId }
      } = event;
      switch (state) {
        case "track": {
          this.localPointMovementX = dx;
          this.localPointMovementY = dy;
          this.localMovementPointId = pointId;
          break;
        }
        case "end": {
          this.localPointMovementX = 0;
          this.localPointMovementY = 0;
          this.localMovementPointId = 0;

          this.$store.commit("movePoint", {
            pointId: pointId,
            widgetId: this.widgetId,
            movementX: dx / this.scale,
            movementY: dy / this.scale
          });
          break;
        }
      }
    },
    // 选中多边形线条
    handlePathTap(event) {
      const { canvas: canvasInfo } = this.$store.state;
      const { x: clientX, y: clientY } = event.detail;

      const[{ x, y }] = document.querySelector('.canvas').getClientRects();
    
      const layerX = clientX - x;
      const layerY = clientY - y;

      this.$store.commit('addNewPoint', {
        offsetX: (layerX / this.scale - this.offsetX - canvasInfo.offsetX),
        offsetY: (layerY / this.scale - this.offsetY - canvasInfo.offsetY),
        pointId: parseInt(event.currentTarget.getAttribute('data-point-id'))
      })
    }
  }
};
</script>>

<style scoped>
.graphics {
  pointer-events: none;
}
.bounds {
  cursor: default;
  pointer-events: stroke;
}
.polygon {
  fill: #398a01;
  fill-opacity: 0.2;
  stroke: #398a01;
  cursor: move;
  pointer-events: fill;
}
.line {
  stroke: #398A01;
  stroke-opacity: 0.01;
  stroke-linecap: round;
}
</style>